using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;


namespace EventBroker
{
	/// <summary>
	/// Represents a publication for a m_strTopic and handles the publication event.
	/// </summary>
	internal class CPublication : IDisposable
	{
		private CEventTopic m_eventTopic;
		private WeakReference m_wrPublisher;
		private string m_strEventName;

		/// <summary>
		/// Initializes a new instance of the publication class
		/// </summary>
		public CPublication(CEventTopic eventTopic_p, object objPublisher_p, string strEventName_p)
		{
			this.m_eventTopic = eventTopic_p;
			this.m_wrPublisher = new WeakReference(objPublisher_p);
			this.m_strEventName = strEventName_p;
			
			EventInfo publishedEvent =
				objPublisher_p.GetType().GetEvent(strEventName_p, BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);

			Delegate dgHandler = Delegate.CreateDelegate(publishedEvent.EventHandlerType, 
                                                       this,
                                                       this.GetType().GetMethod("PublicationHandler"));

			publishedEvent.AddEventHandler(objPublisher_p, dgHandler);
		}

       
        public object Publisher
        {
            get { return m_wrPublisher.Target; }
        }


		/// <summary>
		/// Fires the event publication.
		/// </summary>
		public void PublicationHandler(object objSender_p, EventArgs eventArgs_p)
		{
			m_eventTopic.Fire(objSender_p, eventArgs_p);
		}


		/// <summary>
		/// The m_strName of the event
		/// </summary>
		public string EventName
		{
			get { return m_strEventName; }
		}


		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}


	    protected virtual void Dispose(bool bIsDisposing_p)
		{
			if (bIsDisposing_p)
			{
				object objPublisher = Publisher;
				if (objPublisher != null)
				{
					EventInfo publishedEvent = objPublisher.GetType().GetEvent(m_strEventName);
					publishedEvent.RemoveEventHandler(objPublisher,
						Delegate.CreateDelegate(publishedEvent.EventHandlerType, 
                                                this, 
                                                this.GetType().GetMethod("PublicationHandler")));
				}
			}
		}
	}
}
